CloudFormation入門-ネットワーク環境の作成と組み込み関数-
ご機嫌いかがでしょうか、豊崎です。
先日CloudFormationの肩慣らし記事を書きました。
今回は先日作成したstackを更新してリソースを追加していきたいと思います。
準備
環境にリソースを追加する前にCloudFormationの組み込み関数を押さえておきましょう。
CloudFormationを実行するまでわからない値をプロパティに代入するために組み込み関数は使用されます。 今回は「Ref」,「!GetAtt」のみの利用で対応できる内容にしています。
- Fn::Base64
- 条件関数
- Fn::FindInMap
- Fn::GetAtt
- Fn::GetAZs
- Fn::ImportValue
- Fn::Join
- Fn::Select
- Fn::Sub
- Ref
組み込み関数について詳しくは弊社のブログをご参照ください。
AWS CloudFormation テンプレートリファレンス – 組み込み関数(Intrinsic Function)
作成する内容
web3層構造のネットワーク部分の環境とDataSubnetからインターネット通信をするためのNATGatewayを作成します。
*作成したテンプレートを実行すると課金が発生しますので、各自ご判断の上実施ください!!
- VPC(前回作成済み)
- InternetGateway
- NATGateway
- FrontSubnet(1a/1c)
- AppSubnet(1a/1c)
- DataSubnet(1a/1c)
- PublecRouteTableFrontRoute(Front)
- PrivateRouteTableDataRoute(App/Data)
CloudFormationテンプレート
### AWSTemplateFormatVersion: "2010-09-09" Resources: ### Create VPC MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: "true" EnableDnsHostnames: "true" InstanceTenancy: default Tags: - Key: Name Value: MyVPC # ここからが今回の内容です ### CreateInternetGateway #### InternetGateway MyIGW: Type: "AWS::EC2::InternetGateway" Properties: Tags: - Key: Name Value: IGW #### AttacheInternetGatewayToVPC MyIGWAttachVPC: Type: "AWS::EC2::VPCGatewayAttachment" Properties: InternetGatewayId: !Ref MyIGW VpcId: !Ref MyVPC # 組み込み関数の「!Ref」を使用してリソース名を取得しています ### CreateNATGateway #### Elastic IP for NatGateway MyEIPforNATGW: Type: "AWS::EC2::EIP" Properties: Domain: vpc #### NatGateway MyNATGW: Type: "AWS::EC2::NatGateway" Properties: AllocationId: !GetAtt MyEIPforNATGW.AllocationId # 組み込み関数の「!GetAtt」を使用してリソースの属性を取得しています SubnetId: !Ref MyFrontSubnet1a ### CreateSubnet #### FrontSubnet1a MyFrontSubnet1a: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref MyVPC AvailabilityZone: ap-northeast-1a CidrBlock: 10.0.0.0/24 MapPublicIpOnLaunch: true Tags: - Key: Name Value: MyFrontSubnet1a #### FrontSubnet1c MyFrontSubnet1c: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref MyVPC AvailabilityZone: ap-northeast-1c CidrBlock: 10.0.1.0/24 MapPublicIpOnLaunch: true Tags: - Key: Name Value: MyFrontSubnet1c #### MyAppSubnet1a MyAppSubnet1a: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref MyVPC AvailabilityZone: ap-northeast-1a CidrBlock: 10.0.10.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: MyAppSubnet1a #### MyAppSubnet1c MyAppSubnet1c: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref MyVPC AvailabilityZone: ap-northeast-1c CidrBlock: 10.0.11.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: MyAppSubnet1c #### MyDataSubnet1a MyDataSubnet1a: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref MyVPC AvailabilityZone: ap-northeast-1a CidrBlock: 10.0.20.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: MyDataSubnet1a #### MyDataSubnet1c MyDataSubnet1c: Type: "AWS::EC2::Subnet" Properties: VpcId: !Ref MyVPC AvailabilityZone: ap-northeast-1c CidrBlock: 10.0.21.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: MyDataSubnet1c ###CreateRouteTable #### MyPublicRouteTable MyPublicRouteTable: Type: "AWS::EC2::RouteTable" Properties: VpcId: !Ref MyVPC Tags: - Key: Name Value: MyPublicRouteTable RouteAddInternet: Type: "AWS::EC2::Route" Properties: DestinationCidrBlock: "0.0.0.0/0" GatewayId: !Ref MyIGW RouteTableId: !Ref MyPublicRouteTable AssociateMyFrontSubnet1aToMyPublicRouteTable: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: RouteTableId: !Ref MyPublicRouteTable SubnetId: !Ref MyFrontSubnet1a AssociateMyFrontSubnet1cToMyPublicRouteTable: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: RouteTableId: !Ref MyPublicRouteTable SubnetId: !Ref MyFrontSubnet1c #### MyPrivateRouteTable MyPrivateRouteTable: Type: "AWS::EC2::RouteTable" Properties: VpcId: !Ref MyVPC Tags: - Key: Name Value: MyPrivateRouteTable RouteAddNATGateway: Type: "AWS::EC2::Route" Properties: DestinationCidrBlock: "0.0.0.0/0" NatGatewayId: !Ref MyNATGW RouteTableId: !Ref MyPrivateRouteTable AssociateMyAppSubnet1aToMyPublicRouteTable: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: RouteTableId: !Ref MyPrivateRouteTable SubnetId: !Ref MyAppSubnet1a AssociateMyAppSubnet1cToMyPublicRouteTable: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: RouteTableId: !Ref MyPrivateRouteTable SubnetId: !Ref MyAppSubnet1c AssociateMyFrontSubnet1aToMyPrivateRouteTable: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: RouteTableId: !Ref MyPrivateRouteTable SubnetId: !Ref MyDataSubnet1a AssociateMyFrontSubnet1cToMyPrivateRouteTable: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: RouteTableId: !Ref MyPrivateRouteTable SubnetId: !Ref MyDataSubnet1c
ChangeSet(更新箇所の確認)
上記のCloudFormationテンプレートを任意の名前で保存してAWSCLIから更新リソースの確認をします。 ChangeSetはアップデートを実行する前にどのような変更が加えられるかを簡易的に確認することができる機能です。 それでは実際に行いましょう。
$ aws cloudformation create-change-set --stack-name cm-vpc --change-set-name cm-updatestack1 --template-body file://cloudformation-update1.yml ### 実際には1行です。 { "StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXX:stack/cm-vpc/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "Id": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:changeSet/cm-updatestack1/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX" } $ aws cloudformation describe-change-set --change-set-name cm-updatestack1 --stack-name cm-vpc ### 実際には1行です。 { "StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXX:stack/cm-vpc/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "Status": "CREATE_COMPLETE", "ChangeSetName": "cm-updatestack1", "Changes": [ { "ResourceChange": { "Action": "Add", "ResourceType": "AWS::EC2::SubnetRouteTableAssociation", "Scope": [], "Details": [], "LogicalResourceId": "AssociateMyAppSubnet1aToMyPublicRouteTable" }, "Type": "Resource" }, ・ ・中略 ・ { "ResourceChange": { "Action": "Add", "ResourceType": "AWS::EC2::Route", "Scope": [], "Details": [], "LogicalResourceId": "RouteAddInternet" }, "Type": "Resource" } ], "CreationTime": "2017-03-19T02:54:31.281Z", "Capabilities": [], "StackName": "cm-vpc", "NotificationARNs": [], "ExecutionStatus": "AVAILABLE", "ChangeSetId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:changeSet/cm-updatestack1/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX" }
今回はリソースの追加だけなので、Actionが「Add」となっていますが、「Modify」、「Remove」があります。 また、Actionが「Modify」の時、リソースの置き換え(作り直し)が発生するかどうかをReplacementで教えてくれます。
コマンドで実行しましたが、もちろんAWSメネジメントコンソールで実行することも可能です。 その場合は以下のように表示されます。さすがにGUIの方がわかりやすいですね。
UpdateStack(実際の更新)
それでは前回作成したStack(VPCのみ)を更新してネットワーク環境を作成しましょう。
*繰り返しになりますが、上記CloudFormationテンプレートを実行すると課金が発生します。
$ aws cloudformation execute-change-set --change-set-name cm-updatestack1 --stack-name cm-vpc ### 実際には1行です。
さいごに
今回作成したCloudFormationテンプレートでネットワーク環境が作成できます。 ここまで作ってしまえば好きなようにサブネット内にEC2などを構築することができます。 またyaml形式で記載することでコメントの記載や、リソースのブロックごとに行間を開けるなど可読性も高まりますね。